#include "./project.h"

// 初始化lcd参数
LCD_P lcd_init()
{
    LCD_P lcd_struct = (LCD_P)malloc(sizeof(LCD));
    if (lcd_struct == (LCD_P)NULL)
    {
        perror("mallo_lcd");
        return (LCD_P)-1;
    }
    memset(lcd_struct, 0, sizeof(LCD));
    lcd_struct->fp_dev = open(LCD_PATH, O_RDWR);
    if (lcd_struct->fp_dev == -1)
    {
        perror("open_dev");
        return (LCD_P)-1;
    }
    lcd_struct->fp_input = open(TOUCH_PATH, O_RDWR);
    if (lcd_struct->fp_input == -1)
    {
        perror("open_dev");
        return (LCD_P)-1;
    }

    if (ioctl(lcd_struct->fp_dev, FBIOGET_VSCREENINFO, &(lcd_struct->var)) == -1)
    {
        perror("var");
        return (LCD_P)-1;
    }
    lcd_struct->lcd_w = lcd_struct->var.xres;
    lcd_struct->lcd_h = lcd_struct->var.yres;
    lcd_struct->touch_x = -1;
    lcd_struct->touch_y = -1;
    lcd_struct->map_dev = (int *)mmap(NULL, (lcd_struct->lcd_w) * (lcd_struct->lcd_h) * 4, PROT_READ | PROT_WRITE,
                                      MAP_SHARED, lcd_struct->fp_dev, 0);
    if (lcd_struct->map_dev == (int *)MAP_FAILED)
    {
        perror("map");
        return (LCD_P)-1;
    }
    lcd_struct->fp_font = open("asci.Dzk", O_RDWR);
    lcd_struct->font_size = lseek(lcd_struct->fp_font, 0, SEEK_END);
    lseek(lcd_struct->fp_font, 0, SEEK_SET);
    lcd_struct->map_font = (char *)mmap(NULL, lcd_struct->font_size, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_struct->fp_font, 0);
    if (lcd_struct->map_font == (char *)MAP_FAILED)
    {
        perror("map font");
        return false;
    }
    Show_One_Thumbnail(lcd_struct, "ui/bu.bmp", 1, 0, 0);
    start_ai_show(lcd_struct);

    return lcd_struct;
}
bool start_ai_show(LCD_P lcd)
{
    int *new_map = lcd->map_dev;
    float x0 = 0.0;
    for (int y = 460; y < 480; y++)
    {
        for (int x = 0; x < 800; x++)
        {
            *(new_map + 800 * y + x) = 0x00ffffff;
        }
    }

    Show_One_Thumbnail(lcd, "ui/bai.bmp", 1, 784, 464);
    for (int x = 0; x < 745; x++)
    {
        for (int y = 464; y < 480; y++)
        {
            *(new_map + 800 * y + x) = 0x0097d4f7;
        }
        x0 += 1.0;
        usleep(1000);
        if (x < 750 && x % 4 == 0)
        {

            Show_One_Thumbnail(lcd, "ui/luo.bmp", 1, 0, 444);
            Show_One_Thumbnail(lcd, "ui/plane.bmp", 1, x, 444);
        }
        sprintf(lcd->start_ai, "%.0f", x0 / 800.0 * 100.0);
        line(lcd, lcd->start_ai, 745, 464);
    }
    line(lcd, "100", 745, 464);
    usleep(10000);
    return true;
}
// 主控页面
bool main_interface(LCD_P lcd)
{
    // printf("1\n");
    Original_bmp_show(lcd, "/ui/main.bmp");
    // line(lcd, lcd->time_buf, 80, 0);
    printf("---------------%s\n", lcd->time_buf);
    while (1)
    {

        get_touch_pos(lcd);

        if (lcd->touch_x > 180 && lcd->touch_x < 320 && lcd->touch_y > 110 && lcd->touch_y < 210)
        {
            // printf("11111111dadadaadadasadadadaddada\n");
            main_game(lcd);
        }
        else if (lcd->touch_x > 440 && lcd->touch_x < 580 && lcd->touch_y > 110 && lcd->touch_y < 210)
        {
            main_album(lcd);
        }
        else if (lcd->touch_x > 180 && lcd->touch_x < 320 && lcd->touch_y > 270 && lcd->touch_y < 370)
        {
            printf("vido\n");
        }
        else if (lcd->touch_x > 440 && lcd->touch_x < 580 && lcd->touch_y > 270 && lcd->touch_y < 370)
        {
            printf("exit\n");
            Show_One_Thumbnail(lcd, "/ui/exit_all.bmp", 1, 0, 0);
            return true;
        }
        Original_bmp_show(lcd, "/ui/main.bmp");
        lcd->touch_x = -1;
        lcd->touch_y = -1;
    }

    return true;
}
// 释放空间
bool free_all(LCD_P lcd)
{
    while (lcd->album_General->bmp_header->next != lcd->album_General->bmp_header)
    {
        BMP_P node = lcd->album_General->bmp_header->next;
        lcd->album_General->bmp_header->next = node->next;
        node->next->prev = lcd->album_General->bmp_header;
        node->next = node;
        node->prev = node;
        free(node);
        // printf("释放bmp\n");
    }
    free(lcd->album_General->bmp_header);
    lcd->album_General = NULL;
    free(lcd->album_General);
    free(lcd->game_General);
    if (close(lcd->fp_dev) == -1)
    {
        perror("fp_dev");
        return false;
    }
    if (close(lcd->fp_font) == -1)
    {
        perror("fp_font");
        return false;
    }
    if (close(lcd->fp_input) == -1)
    {
        perror("fp_input");
        return false;
    }
    if (munmap(lcd->map_dev, lcd->lcd_w * lcd->lcd_h * 4) == -1)
    {
        perror("map_dev");
        return false;
    }
    if (munmap(lcd->map_font, lcd->font_size) == -1)
    {
        perror("map_font");
        return false;
    }
    free(lcd);
    return true;
}
void *get_time_thread(void *arg)
{
    LCD_P lcd = (LCD_P)arg;
    // time_t rawtime;
    // struct tm *timeinfo;
    // char buffer[80];
    time_t timer;
    struct tm *t;

    while (1)
    {
        // time(&rawtime); // 获取时间戳（秒级）
        // // localtime_r(&rawtime, &timeinfo); // 线程安全转换本地时间:ml-citation{ref="5,6" data="citationList"}
        // timeinfo = localtime(&rawtime);
        // // strftime(lcd->time_buf, sizeof(lcd->time_buf), "%H:%M:%S", &timeinfo);
        // // printf("Current time: %s\n", lcd->time_buf);
        // printf("%s\n", asctime(timeinfo));
        // line(lcd, asctime(timeinfo), 100, 0);

        time(&timer);          // 获取当前时间戳
        t = localtime(&timer); // 转换为本地时间（假设系统时区已设置为UTC+8）

        // 格式化输出北京时间
        // printf("当前北京时间: %04d年%02d月%02d日 %02d:%02d:%02d\n",
        //        t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
        //        t->tm_hour, t->tm_min, t->tm_sec);
        sprintf(lcd->time_buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
        line(lcd, lcd->time_buf, 100, 0);

        sleep(1); // 每秒更新一次
    }
    return NULL;
}

// 刷白屏
bool show_white_screen(LCD_P lcd)
{
    int *new_map = lcd->map_dev;
    for (int y = 0; y < 480; y++)
    {
        for (int x = 0; x < 800; x++)
        {
            *(new_map + 800 * y + x) = 0x00ffffff;
        }
    }
    return true;
}

// 查找bmp图片路径
bool bmp_path_search(LCD_P lcd)
{
    DIR *dp = opendir(BMP_PATH);
    if (dp == (DIR *)NULL)
    {
        perror("打开文件");
        return false;
    }
    while (1)
    {
        struct dirent *eq = readdir(dp);
        if (eq == (struct dirent *)NULL)
        {
            break;
        }
        if (eq->d_name[0] == '.')
        {
            continue;
        }
        if (strcmp(&(eq->d_name[strlen(eq->d_name) - 4]), ".bmp") == 0)
        {
            BMP_P node = create_bmp_node();
            if (node == (BMP_P)-1)
            {
                return false;
            }
            sprintf(node->bmp_path, "%s/%s", BMP_PATH, eq->d_name);
            strcpy(node->bmp_name, eq->d_name);
            add_bmp_node(lcd, node);
        }
    }
    return true;
}
// 获得lcd——touch坐标
bool get_touch_pos(LCD_P lcd)
{
    struct input_event touch;
    while (1)
    {
        if (read(lcd->fp_input, &touch, sizeof(touch)) == -1)
        {
            perror("read touch lcd ...");
            return false;
        }
        if (touch.type == EV_ABS && touch.code == ABS_X)
            lcd->touch_x = touch.value * lcd->lcd_w / 1024;
        if (touch.type == EV_ABS && touch.code == ABS_Y)
            lcd->touch_y = touch.value * lcd->lcd_h / 600;
        if (touch.type == EV_KEY && touch.code == BTN_TOUCH && touch.value == 0)
        {
            break;
        }
    }
    return true;
}
// touch_方向
bool touch_direction(LCD_P lcd)
{
    int start_x = -1;
    int start_y = -1;
    int end_x = -1;
    int end_y = -1;
    int move_x = -1;
    int move_y = -1;
    struct input_event evt;
    while (1)
    {
        if (read(lcd->fp_input, &evt, sizeof(evt)) == -1)
        {
            perror("2");
            return false;
        }
        if (evt.type == EV_ABS && evt.code == ABS_X)
        {
            move_x = evt.value;
            lcd->touch_x = evt.value * lcd->lcd_w / 1024;
        }
        if (evt.type == EV_ABS && evt.code == ABS_Y)
        {
            move_y = evt.value;
            lcd->touch_y = evt.value * lcd->lcd_h / 600;
        }
        if (start_x == -1)
        {
            start_x = move_x;
        }
        if (start_y == -1)
        {
            start_y = move_y;
        }
        if (evt.type == EV_KEY && evt.code == BTN_TOUCH && evt.value == 0)
        {
            end_x = move_x;
            end_y = move_y;
            int abs_x = abs(start_x - end_x);
            int abs_y = abs(start_y - end_y);
            if (abs_x > abs_y && abs_x > 50)
            {
                if (start_x > end_x)
                {
                    lcd->album_General->direction = 4;
                }
                else
                {

                    lcd->album_General->direction = 2;
                }
                lcd->touch_x = -1;
                lcd->touch_y = -1;
            }
            else if (abs_x < abs_y && abs_y > 50)
            {
                if (start_y > end_y)
                {

                    lcd->album_General->direction = 1;
                }
                else
                {
                    lcd->album_General->direction = 3;
                }
                lcd->touch_x = -1;
                lcd->touch_y = -1;
            }
            else
            {
                lcd->album_General->direction = 0;
            }
            start_x = -1;
            start_y = -1;
            end_x = -1;
            end_y = -1;
            move_x = -1;
            move_y = -1;
            return true;
        }
    }
    return false;
}

// 字体
bool show_font_one(LCD_P lcd, char letter, int where_x, int where_y)
{
    int offest = letter * 32;
    char *new_map_font = lcd->map_font + offest;
    int *new_map_dev = lcd->map_dev + lcd->lcd_w * where_y + where_x;
    for (int y = 0; y < 16; y++)
    {
        for (int x = 0; x < 2; x++)
        {
            char type = *(new_map_font + y * 2 + x);
            for (int z = 0; z < 8; z++)
            {
                if (type & (0x80 >> z))
                {

                    *(new_map_dev + lcd->lcd_w * y + (8 * x + z)) = 0x000000ff;
                }
                else
                {
                    *(new_map_dev + lcd->lcd_w * y + (8 * x + z)) = 0x00ffffff;
                }
            }
        }
    }
    return true;
}
bool line(LCD_P lcd, char *buf, int x, int y)
{
    for (int i = 0; i < strlen(buf); i++)
    {
        if (show_font_one(lcd, buf[i], x, y) == false)
        {
            return false;
        }
        x += 12;
        if (x >= 788)
        {
            x = 0;
            y += 12;
        }
    }
    return true;
}
// 获得lcd——touch坐标
bool get_touch_move(LCD_P lcd)
{
    struct input_event touch;
    while (1)
    {
        if (read(lcd->fp_input, &touch, sizeof(touch)) == -1)
        {
            perror("read touch lcd ...");
            return false;
        }
        if (touch.type == EV_ABS && touch.code == ABS_X)
            lcd->game_General->move_x = touch.value * lcd->lcd_w / 1024;
        if (touch.type == EV_ABS && touch.code == ABS_Y)
            lcd->game_General->move_y = touch.value * lcd->lcd_h / 600;
        printf("121212122\n");
    }
    return true;
}